package rmi.farted;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;

/** FartServ mit RMI
 * @author J. Schoch
 * @version 1.0 -- erstes Ger�st f�r einen Server
 * @date Okt. 2010
 */
public class FartServ extends UnicastRemoteObject implements ServerInterpreter {
	static final long serialVersionUID = 123456789;
	private StringBuffer result;
	private boolean debug = true;
	
	// Pressed Characters
	PressedChar pressedChar;
	
	// Clients
	private static int maxNrOfClients = 8;	// maximale Anzahl an Clients, welche registriert werden k�nnen
	private int actNrOfClients = 0;			// aktuelle Anzahl registrierter Clients
	HashMap<Integer,ClientInterpreter> clients = new HashMap<Integer, ClientInterpreter>(maxNrOfClients);
	
	// Parameterlosen Konstruktor - n�tig
	public FartServ() throws Exception {
		LocateRegistry.createRegistry(2020);
		Naming.rebind("rmi://localhost:2020/FartServ",this);	// Anmeldung beim RMIRegistry
		debug("FartServ ready.");
    }

	/*
	 * (non-Javadoc)
	 * @see remote.ServerInterpreter#interpretKeyPressed(int, int, int, int, int)
	 */
	public void interpretKeyPressed(int userID, int hashValueText, char keyID, int keyPosRow, int keyPosCol) {
		pressedChar = new PressedChar(userID, hashValueText, keyID, keyPosRow, keyPosCol);	// define the pressed character
		
		// just for debug
		result = new StringBuffer();
		result.append("Pressed Key: <");
		result.append(keyID);
		result.append(">");
		debug(result.toString());

		pushClients(pressedChar);
		pressedChar = null;
	}
	
	/*
	 * implementierung der Client Registrierung(non-Javadoc)
	 * @see remote.ServerInterpreter#registerClient(remote.ClientInterpreter)
	 */
	public int registerClient(ClientInterpreter client) throws RemoteException {		
		if (actNrOfClients < maxNrOfClients) {
			actNrOfClients++;
			clients.put(actNrOfClients, client); // client registrieren
			debug("client registered: " + client.toString());
			return actNrOfClients;	// gew�hlte userID dem Benutzer dur�ckgeben
		}
		//this.client = client;	// einfache Variante f�r einen Client
		debug("max nr. of clients reached!");
		return 0; // fail
	}
	
	/*
	 * pushes something to the client -> wake it up
	 */
	private void pushClients(PressedChar character) {
		int userID;
		
		try {
			for (userID = 0; userID <= maxNrOfClients; userID++) {	// durch alle Clients iterieren
				if (character.getUserID() != userID) {				// zeichen nicht an sendenden user zur�cksenden
					if (clients.containsKey(userID)) {				// wenn ein client registriert
						clients.get(userID).printChar(character.getKeyID(), character.getKeyPosRow(), character.getKeyPosCol());	// print on clients
						debug("Character <" + character.getKeyID() + "> sent to client with userID: " + userID);
					}
				}	
			} 
		} catch (RemoteException e_remote) {
			System.err.println("Fail to send Character to client!");
				e_remote.printStackTrace();
		}
	}

	/*
	 * MAIN
	 */
	public static void main(String[] args) throws Exception {
		new FartServ();	// hiermit startet der server
    }

	
	
	// Konsolenausgabe
	private void debug(String text) {
		if (debug) System.out.println(text);
	}
	
	
	// Hilfsbetriebe -------------------------------------------------------------

	/** Split a text line into words.<p>
	 *
	 * @return String[] containing individual words at indices 1..n;<br>
	 * index 0 holds text consisting of words 2..n (remainder of text line)
	 */

//	public static String[] words(String s) {
//		StringTokenizer st = new StringTokenizer(s.trim());
//		StringBuffer sb = new StringBuffer();
//		int t = st.countTokens();
//		String[] args = new String[t+1];
//		for (t=1; st.hasMoreTokens(); t++) {
//			args[t] = st.nextToken().trim();
//			if (t>1) {sb.append(args[t]); sb.append(" ");}
//		}
//		args[0] = sb.toString().trim();
//		return(args);
//	}

   } // FartServ close
